<?php
/*! \brief
 * This is WFMigrateFactory class
 * This is the Migrate Factory Class that create relative Migrate Class
 * \author William Su
 */
class WFMigrateFactory
{
    private static $instance;
    /**
     * @var WF
     */
    private $objFramework;
    private $arrWFVersionForUpgrade = array('1.6','2.0','3.0');
    public function __construct($objFramework){
        $this->objFramework = $objFramework;
    }
    public static function getDirnameFile(){
        if(! isset(self::$instance[__FUNCTION__])){
            self::$instance[__FUNCTION__] = dirname(__FILE__);
        }
        return self::$instance[__FUNCTION__];
    }
    /**
     * @return WFMigrate16to20
     */
    public function getMigrate($strWFFromTo = null){
        if(! isset(self::$instance[__FUNCTION__][$strWFFromTo])){
            $srcFolderNameWidgetOldInstall = $this->getFolderNameWidgetOldInstall();
            if((null !== $strWFFromTo && '20to20' == $strWFFromTo) || true === file_exists($this->objFramework->getDocumentRoot() . '/../' . $srcFolderNameWidgetOldInstall . '/inc/config.php')){
                require_once self::getDirnameFile() . '/Migrate20to20.php';
                self::$instance[__FUNCTION__][$strWFFromTo] = new WFMigrate20to20($this->getWFFrom(), $this->getWFTo());
            }elseif((null !== $strWFFromTo && '16to20' == $strWFFromTo) || true === file_exists($this->objFramework->getDocumentRoot() . '/../' . $srcFolderNameWidgetOldInstall . '/includes/config.php')){
                require_once self::getDirnameFile() . '/Migrate16to20.php';
                self::$instance[__FUNCTION__][$strWFFromTo] = new WFMigrate16to20($this->getWFFrom(), $this->getWFTo());
            }else{
                $strMsg = __CLASS__ . '::' . __FUNCTION__ . '()=>Failed to get object WFMigrate!';
                throw new WFMigrateException($strMsg);
            }
        }
        return self::$instance[__FUNCTION__][$strWFFromTo];
    }
	/**
     * @return WFCollection
     */
    public function getColMigrate($strWFFromTo = null){
        if(! isset(self::$instance[__FUNCTION__][$strWFFromTo])){
            $col = $this->objFramework->getCollection();
            $srcFolderNameWidgetOldInstall = $this->getFolderNameWidgetOldInstall();
            
            if(null !== $strWFFromTo){
                $strMigrateClassNameWithoutPrefix = 'Migrate'.$strWFFromTo;
                $strPathMigrateFile =  self::getDirnameFile() . '/'.$strPathMigrateFile.'.php';
                if(file_exists($strPathMigrateFile)){
                    require_once $strPathMigrateFile;
                    $strClassName = 'WF'.$strMigrateClassNameWithoutPrefix;
                    $col->add(new $strClassName($this->getWFFrom(), $this->getWFTo()));
                }
                
            }else{
                $strVersionFrom = $this->getWFFrom()->getWFVersion();
                $strVersionTo = $this->getWFTo()->getConfigFactory()->getConfig()->getVersion();
                
                $indexVersionFrom = array_search($strVersionFrom, $this->arrWFVersionForUpgrade);
                $indexVersionTo = array_search($strVersionTo, $this->arrWFVersionForUpgrade);
                if($indexVersionFrom !== false && $indexVersionTo !== false){
                	// Scenario 1 : 3.0 external beta migrate to 3.0 GM
                	if($indexVersionFrom == $indexVersionTo){ 
                		$arrWFVersionForUpgradeTmp = array($this->arrWFVersionForUpgrade[$indexVersionFrom], $this->arrWFVersionForUpgrade[$indexVersionTo]);
               		// Scenario 2 : low version migrate to high version
                	}else{ 
                    	$arrWFVersionForUpgradeTmp = array_slice($this->arrWFVersionForUpgrade, $indexVersionFrom, ($indexVersionTo-$indexVersionFrom)+1);
                	}
                    if(count($arrWFVersionForUpgradeTmp) >= 2){
                        do{
                            $strWFVersionFrom = str_replace('.', '', $arrWFVersionForUpgradeTmp[0]);
                            $strWFVersionTo = str_replace('.', '', $arrWFVersionForUpgradeTmp[1]);
                            
                            $strMigrateClassNameWithoutPrefix = 'Migrate'.$strWFVersionFrom.'to'.$strWFVersionTo;
                            $strPathMigrateFile =  self::getDirnameFile() . '/'.$strMigrateClassNameWithoutPrefix.'.php';
                            if(file_exists($strPathMigrateFile)){
                                $strMigrateProductClassNameWithoutPrefix = 'Migrate'.$strWFVersionFrom.'to'.$strWFVersionTo.'Product';
                                $strPathMigrateProductFile =  $this->objFramework->getWidgetPoolFactory()->getWPHome() . '/inc/class/migrate/'.$strMigrateProductClassNameWithoutPrefix.'.php';
                                if(file_exists($strPathMigrateProductFile)){
                                    require_once $strPathMigrateProductFile;
                                    $strClassName = 'WF'.$strMigrateProductClassNameWithoutPrefix;
                                }else{
                                require_once $strPathMigrateFile;
                                $strClassName = 'WF'.$strMigrateClassNameWithoutPrefix;
                                }
                                $col->add(new $strClassName($this->getWFFrom(), $this->getWFTo()));
                            }
                            
                            array_shift($arrWFVersionForUpgradeTmp);
                        }while(count($arrWFVersionForUpgradeTmp) >= 2);
                    }
                }
            }
            self::$instance[__FUNCTION__][$strWFFromTo] = $col;
        }
        return self::$instance[__FUNCTION__][$strWFFromTo];
    }
    /**
    /**
     *\brief Description
     * This method will return object of WFDataObject
     * @return WFDatabaseObjectSqlite
     */
    /*public function getDataObjectTo(){
		return $this->objFramework->getDataObject();
	}*/
    /**
     * @return WF
     */
    public function getWFTo(){
        return $this->objFramework;
    }
    /**
     * //return WFFrom20
     * @return WF
     */
    public function getWFFrom(){
        if(! isset(self::$instance[__FUNCTION__])){
            $srcFolderNameWidgetOldInstall = $this->getFolderNameWidgetOldInstall();
            if(true === file_exists($this->objFramework->getDocumentRoot() . '/../' . $srcFolderNameWidgetOldInstall . '/inc/config.php')){
            	require($this->objFramework->getDocumentRoot() . '/../' . $srcFolderNameWidgetOldInstall . '/inc/config.php');
            	$strVersion = str_replace('.', '', $wfconf_version);
            	$strClassName = 'WFFrom'.$strVersion;
                require_once self::getDirnameFile() . '/'.$strClassName.'.php';
                self::$instance[__FUNCTION__] = new $strClassName($this->objFramework);
            }elseif(true === file_exists($this->objFramework->getDocumentRoot() . '/../' . $srcFolderNameWidgetOldInstall . '/includes/config.php')){
                require_once self::getDirnameFile() . '/WFFrom16.php';
                self::$instance[__FUNCTION__] = new WFFrom16($this->objFramework);
            }else{
                $strMsg = __CLASS__ . '::' . __FUNCTION__ . '()=>Failed to get object WFFrom!';
                throw new WFMigrateException($strMsg);
            }
        }
        return self::$instance[__FUNCTION__];
    }
    public function getFolderNameWidgetInstall(){
        $srcFolderName = $this->objFramework->isUnitTest() ? 'src' : 'widget';
        return $srcFolderName;
    }
    public function getFolderNameWidgetOldInstall(){
        $srcFolderName = $this->objFramework->isUnitTest() ? 'build/src_old' : 'widget_old';
        return $srcFolderName;
    }
}
